﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SkypeStudio.Framework;
using SkypeStudio.Controls.Views;
using System.ComponentModel.Composition;
using System.Collections.ObjectModel;
using SkypeStudio.Controls.Model;
using SkypeStudio.Controls.Services;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Data;

namespace SkypeStudio.Controls.ViewModels
{
    [Export]
    public class ChatListViewModel : ViewModelBase<IChatListView>, IDisposable
    {
        private void OnRequestOpendChat(Chat obj)
        {
            Action<Chat> handler = RequestOpendChat;
            if (handler != null)
                handler(obj);
        }
        public event Action<Chat> RequestOpendChat;

        private ObservableCollection<Chat> _Chats;
        private ISkypeApplicationService _SkypeService;

        [ImportingConstructor]
        public ChatListViewModel(IChatListView view, ISkypeApplicationService skypeService)
            : base(view)
        {
            _SkypeService = skypeService;
            _SkypeService.SkypeProcessAttachStatusChanged += SkypeServiceSkypeProcessAttachStatusChanged;
            _SkypeService.MessageReceived += SkypeServiceMessageReceived;
            _SkypeService.MessageSending += SkypeServiceMessageSending;
            _SkypeService.ContactOnlineStatusChanged += SkypeServiceContactOnlineStatusChanged;

            _SkypeService.Chats.CollectionChanged += ChatsCollectionChanged;
        }

        private void ChatsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            RefreshChatListView();
        }

        private void RefreshChatListView()
        {
            NotifyOfPropertyChange(() => Chats);

            ICollectionView collectionView = CollectionViewSource.GetDefaultView(Chats);
            collectionView.Refresh();
        }
        void SkypeServiceContactOnlineStatusChanged(Contact c)
        {
            foreach (Chat item in Chats)
            {
                var matchUser = item.Members.Where(o => o.Handle == c.Handle);
                foreach (Contact contact in matchUser)
                {
                    contact.OnlineStatus = c.OnlineStatus;
                }
            }

            RefreshChatListView();
        }

        void SkypeServiceMessageSending(ChatMessage obj)
        {
            if (Chats.Any(c => c.ChatName == obj.ChatName))
            {
                Chats.First(c => c.ChatName == obj.ChatName).ChatMessages.Add(obj);
            }
            else
            {
                var chat = new Chat() { ChatName = obj.ChatName, ChatMessages = new ObservableCollection<ChatMessage>(), Members = new ObservableCollection<Contact>() };
                chat.Members.Add(obj.User);
                chat.ChatMessages.Add(obj);
                Chats.Add(chat);
            }
        }

        void SkypeServiceSkypeProcessAttachStatusChanged(SkypeProcessAttachStatus obj)
        {
            RefreshChatListView();
        }

        void SkypeServiceMessageReceived(ChatMessage obj)
        {
            if (Chats.Any(c => c.ChatName == obj.ChatName))
            {
                Chats.First(c => c.ChatName == obj.ChatName).ChatMessages.Add(obj);
            }
            else
            {
                var chat = new Chat() { ChatName = obj.ChatName, ChatMessages = new ObservableCollection<ChatMessage>(), Members = new ObservableCollection<Contact>() };
                chat.Members.Add(obj.User);
                chat.ChatMessages.Add(obj);
                Chats.Add(chat);

            }
        }

        public ObservableCollection<Chat> Chats
        {
            get
            {
                //if (_Chats == null)
                //{
                //    _Chats = new ObservableCollection<Chat>(_SkypeService.GetChatList());
                //}
                //return _Chats;
                return this._SkypeService.Chats;
            }
        }

        public void Dispose()
        {
            if (_SkypeService != null)
            {
                _SkypeService.SkypeProcessAttachStatusChanged -= SkypeServiceSkypeProcessAttachStatusChanged;
                _SkypeService.SkypeProcessAttachStatusChanged -= SkypeServiceSkypeProcessAttachStatusChanged;
                _SkypeService = null;
            }

        }

        private Chat _SelectedChat;
        public Chat SelectedChat
        {
            get
            {
                return _SelectedChat;
            }
            set
            {
                if (_SelectedChat == value)
                    return;
                _SelectedChat = value;
                NotifyOfPropertyChange(() => SelectedChat);
                //OnRequestOpendChat(_SelectedChat);
            }
        }

        private ICommand _ListMouseDoubleClickCommand;
        public ICommand ListMouseDoubleClickCommand
        {
            get
            {
                if (_ListMouseDoubleClickCommand == null)
                {
                    _ListMouseDoubleClickCommand = new RelayCommand(ListMouseDoubleClick);
                }
                return _ListMouseDoubleClickCommand;
            }

        }

        void ListMouseDoubleClick(object param)
        {
            OnRequestOpendChat(this.SelectedChat);
        }
    }
}
